package top.malaoshi.netdisk.ctrl;

import org.springframework.validation.BindException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import top.malaoshi.netdisk.exception.BaseException;
import top.malaoshi.netdisk.vo.JsonCodeMsg;
import top.malaoshi.netdisk.vo.JsonResult;
import top.malaoshi.sprout.validation.HibernateValidatorUtil;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.ValidationException;
import java.util.Set;

@RestControllerAdvice
public class GlobalExceptionHandler {

    //当Controller抛出异常时，由该方法处理
    @ExceptionHandler(Exception.class)
    public JsonResult handlerException(Exception e) {

        e.printStackTrace();//为了便于找到错误
        String msg = e.getMessage();
        if(msg == null || "".equals(msg)){
            msg = e.toString();
        }
        JsonResult res=new JsonResult(JsonCodeMsg.SERVER_ERROR.getCode(), msg);

        return res;
    }
    // 对 SpringBoot Hibernate Validation 抛出的异常做处理
    @ExceptionHandler(value = {BindException.class, ValidationException.class, MethodArgumentNotValidException.class})
    public JsonResult handleValidatedException(Exception e) {
        Set<ConstraintViolation<?>> constraintViolations = null;
        // controlle方法参数是javabean，且不符合验证抛出的异常
        if (e instanceof MethodArgumentNotValidException) {
            MethodArgumentNotValidException ex = (MethodArgumentNotValidException) e;
            constraintViolations = ex.getAllErrors();
        } else if (e instanceof ConstraintViolationException) { // controlle方法参数是字符串或基本数据类型，且不符合验证抛出的异常
            ConstraintViolationException ex = (ConstraintViolationException) e;
            constraintViolations = ex.getConstraintViolations();
        } else if (e instanceof BindException) { // 不加@RequestBody注解，提交json数据时，报此异常
            BindException ex = (BindException) e;
            constraintViolations = ex.getAllErrors();
        }
        String message = HibernateValidatorUtil.getMessage(constraintViolations);
        JsonResult resp = JsonResult.fail(JsonCodeMsg.VALIDATE_FAIL.getCode(), message );
        return resp;
    }

    @ExceptionHandler(BaseException.class)
    public JsonResult handlerBaseException(BaseException e) {
        e.printStackTrace();
        JsonResult res=new JsonResult(e.getCode(),e.getMessage());
        return res;
    }

}
